home *** CD-ROM | disk | FTP | other *** search
- /*
- ShowInitIcon - version 1.0, May 11th, 1995
- This code is intended to let INIT writers easily display an icon at startup time.
- View in Geneva 9pt, 4-space tabs
-
- Written by: Peter N Lewis <peter@mail.peter.com.au>, Jim Walker <JWWalker@aol.com>
- and François Pottier <pottier@dmi.ens.fr>, with thanks to previous ShowINIT authors.
- Send comments and bug reports to François Pottier.
-
- This version features:
- - Short and readable code.
- - Correctly wraps around when more than one row of icons has been displayed.
- - works with System 6
- - Built with Universal Headers & CodeWarrior. Should work with other headers/compilers.
- */
-
- #include "ShowInitIcon.h"
-
- #include <Resources.h>
- #include <Icons.h>
- #include <OSUtils.h>
- #include <LowMem.h>
-
- // You should set SystemSixOrLater in your headers to avoid including glue for SysEnvirons.
-
- // Set this flag to 1 if you want to compile this file into a stand-alone resource (see note below).
- // Set it to 0 if you want to include this source file into your INIT project.
-
- #if 0
- #define ShowInitIcon main
- #endif
-
- // The ShowINIT mechanism works by having each INIT read/write data from these globals.
-
- #define LMGetVCoord() (*((short*)0x092A))
- #define LMGetVCheckSum() (*((short*)0x0928))
- #define LMGetHCoord() (*((short*)0x092C))
- #define LMGetHCheckSum() (*((short*)0x092E))
-
- #define LMSetVCoord(val) (*((short*)0x092A)=(val))
- #define LMSetVCheckSum(val) (*((short*)0x0928)=(val))
- #define LMSetHCoord(val) (*((short*)0x092C)=(val))
- #define LMSetHCheckSum(val) (*((short*)0x092E)=(val))
-
- // Prototypes for the subroutines. The main routine comes first; this is necessary to make THINK C's "Custom Header" option work.
-
- static unsigned short CheckSum (unsigned short x);
- static void ComputeIconRect (Rect* iconRect, Rect* screenBounds);
- static void AdvanceIconPosition (Rect* iconRect);
- static void DrawBWIcon (short iconID, Rect *iconRect);
-
- typedef struct QDStorageStruct QDStorage;
-
- /* Modified to ensure alignment is set for 68k code - DHN */
- #if defined(powerc) || defined (__powerc)
- #pragma options align=mac68k
- #endif
- struct QDStorageStruct {
- QDGlobals qd; // Storage for the QuickDraw globals
- long qdGlobalsPtr; // A5 points to this place; it will contain a pointer to qd
- };
- #if defined(powerc) || defined(__powerc)
- #pragma options align=reset
- #endif
-
- // Main routine.
- pascal void ShowInitIcon (short iconFamilyID, Boolean advance){
- long oldA5; // Original value of register A5
- QDStorage qds; // Fake QD globals
- CGrafPort colorPort;
- GrafPort bwPort;
- Rect destRect;
- SysEnvRec environment; // Machine configuration.
-
- oldA5 = SetA5((long) &qds.qdGlobalsPtr); // Tell A5 to point to the end of the fake QD Globals
- InitGraf(&qds.qd.thePort); // Initialize the fake QD Globals
-
- SysEnvirons(curSysEnvVers, &environment); // Find out what kind of machine this is
-
- ComputeIconRect(&destRect, &qds.qd.screenBits.bounds); // Compute where the icon should be drawn
-
- if (environment.systemVersion >= 0x0700 && environment.hasColorQD) {
- OpenCPort(&colorPort);
- PlotIconID(&destRect, atNone, ttNone, iconFamilyID);
- CloseCPort(&colorPort);
- } else {
- OpenPort(&bwPort);
- DrawBWIcon(iconFamilyID, &destRect);
- ClosePort(&bwPort);
- }
-
- if (advance)
- AdvanceIconPosition (&destRect);
-
- SetA5(oldA5); // Restore A5 to its previous value
- }
-
- // A checksum is used to make sure that the data in there was left by another ShowINIT-aware INIT.
- static unsigned short CheckSum (unsigned short x){
- return ((x << 1) | (x >> 15)) ^ 0x1021;
- }
-
- // ComputeIconRect computes where the icon should be displayed.
- static void ComputeIconRect (Rect* iconRect, Rect* screenBounds){
- if (CheckSum(LMGetHCoord()) != LMGetHCheckSum()) // If we are first, we need to initialize the shared data.
- LMSetHCoord(8);
- if (CheckSum(LMGetVCoord()) != LMGetVCheckSum())
- LMSetVCoord(screenBounds->bottom - 40);
-
- if (LMGetHCoord() + 34 > screenBounds->right) { // Check whether we must wrap
- iconRect->left = 8;
- iconRect->top = LMGetVCoord() - 40;
- } else {
- iconRect->left = LMGetHCoord();
- iconRect->top = LMGetVCoord();
- }
- iconRect->right = iconRect->left + 32;
- iconRect->bottom = iconRect->top + 32;
- }
-
- // AdvanceIconPosition updates the shared global variables so that the next extension will draw its icon beside ours.
- static void AdvanceIconPosition (Rect* iconRect){
- LMSetHCoord(iconRect->left + 40); // Update the shared data
- LMSetVCoord(iconRect->top);
- LMSetHCheckSum(CheckSum(LMGetHCoord()));
- LMSetVCheckSum(CheckSum(LMGetVCoord()));
- }
-
- // DrawBWIcon draws the 'ICN#' member of the icon family. It works under System 6.
- static void DrawBWIcon (short iconID, Rect *iconRect){
- Handle icon;
- BitMap source, destination;
- GrafPtr port;
-
- icon = Get1Resource('ICN#', iconID);
- if (icon) {
- HLock(icon);
- // Prepare the source and destination bitmaps.
- source.baseAddr = *icon + 128; // Mask address.
- source.rowBytes = 4;
- SetRect(&source.bounds, 0, 0, 32, 32);
- GetPort(&port);
- destination = port->portBits;
- // Transfer the mask.
- CopyBits(&source, &destination, &source.bounds, iconRect, srcBic, nil);
- // Then the icon.
- source.baseAddr = *icon;
- CopyBits(&source, &destination, &source.bounds, iconRect, srcOr, nil);
- }
- }
-
- /*
- Notes
-
- Checking for PlotIconID:
- We (PNL) now check for system 7 and colour QD, and use colour graf ports and PlotIconID only if both are true
- Otherwise we use B&W grafport and draw using PlotBWIcon.
-
- 68k Struct Padding:
- I (DHN) added the padding stuff to ensure that everything pads well when building for the PPC. I have been bitten
- already by a non-padded structure that didn't work on a PPC that did on a 68k Mac, so I use the padding religiously now.
-
-
- */
-
-
-